package sj;

/**
 * count++是非原子性操作，volatile在这里没用了！只能用synchronized
 * synchronized 是独占锁/排他锁（就是有你没我的意思），同时只能有一个线程调用 add10K方法，其他调用线程会被阻塞。
 * 所以三行 CPU指令是都在同一个线程执行完之后，别的线程才能继续执行
 */
public class Add10k1_synchronized {
    int count = 0;

    //  修饰非静态方法，锁定的是类的当前实例对象this。加锁本质就是在被锁对象的对象头中写入当前线程id。
    //  当该类中有多个普通方法被Synchronized修饰（同步），那么这些方法的锁都是这个类的一个对象this。
    //  多个线程访问这些方法时，如果这些线程调用方法时使用的是同一个该类的对象，
    //虽然他们访问不同方法，但是他们使用同一个对象来调用，那么这些方法的锁就是一样的，就是这个对象，那么会造成阻塞。
    //  如果多个线程通过不同的对象来调用方法，那么他们的锁就是不一样的，不会造成阻塞。
    synchronized void add10k() {
        int i = 0;
        while (i++ < 10000) {
            count++;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Add10k1_synchronized test = new Add10k1_synchronized();

        // 创建两个线程，执行 add() 操作
        Thread th1 = new Thread(() -> {
            test.add10k();
        });
        Thread th2 = new Thread(() -> {
            test.add10k();
        });

        // 启动两个线程
        th1.start();
        th2.start();
        // 等待两个线程执行结束
        th1.join();
        th2.join();

        System.out.println(test.count);
    }
}
